iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
佛心分享-SideProject30

門外漢的嵌入式地獄系列 第 17

Day 17 。初入嵌入式開發-設備樹 (下)

  • 分享至 

  • xImage
  •  

設備樹當中常見的屬性

  1. compatible

    這是一個字串型態的屬性,用途是把這個設備跟他的驅動程式綁定,像是 m_can 設備就會是 bosch家的驅動。

    **compatible=** "manufacturer,model"
    

    前面是製造商,後面是驅動檔案的名字

    compatible= "bosch,m_can"
    

    當然屬性不是只能放一個,也可以放好幾個值在一個屬性當中。

    compatible= "bosch,m_can" , "bosch1,m_can1"
    

    這樣寫的話當啟動時就會先以第一個值去找有沒有相同的驅動,沒有的話就會去查第二個驅動。

    驅動程式的檔案當中都會有一個 OF Table , 在這個 Table 當中會存放一些 compatible ,如果我們寫的設備 compatible 與當中相同,就可以使用這個驅動。

    static const struct of_device_id adnp_of_match[] = {
        { .compatible = "bosch,m_can", },
        { },
    };
    
  2. model

    這個屬性也是個字串,通常用來說明開發板的名字or設備的訊息 EX:

    model = "st,st32mp157";
    
  3. status

    用來說明這個設備室啟用或是禁用或是有問題

    okay : 表示是可用或是啟動
    disabled : 表示目前禁用,但未來可以隨時開啟,熱插拔功能
    fail : 表示目前禁用,但未來可以隨時開啟
    fail-sss : 表示目前禁用,但未來可以隨時開啟,但sss表示有錯誤

  4. reg

    reg 通常是 <address , length> , reg 屬性一般用於說明設備的地址或者其他的設備地址相關訊息,例如下方是

    外圍的registers地址範圍。

    reg = <0x4000e000 0x400>;   
    /* 這個設備的暫存器開頭地址是0x4000e000,地址長度範圍是0x400(通常該IC的手冊可以找到多大)*/
    // 簡單來說就是開頭位置,然後範圍有多大。
    
  5. #address-cells 和 #size-cells

    這個屬性是 uint_32 的 type , 用在任何一個擁有子節點的設備當中,用來說明子節點的地址資訊。

    #address-cells : 指定節點中地址的長度,以單位數量表示。例如,#address-cells = <1>; 表示節點中每個地址由1個單位(通常是32位元或64位元整數)構成。這表示在此節點的 reg 屬性中,地址值將以1個單位來表示。
    如果設為 <1>,表示地址由1個單位組成(例如,一個32位的整數)。如果設為 <2>,則地址由2個單位組成(例如,兩個32位的整數,通常用於64位地址)。

    #size-cells : 指定節點中大小的長度,以單位數量表示。例如,#size-cells = <0>; 表示節點中沒有需要描述的大小數量,或者說此節點的 reg 屬性中沒有大小資訊。這通常用於那些不需要指定大小的節點。
    如果設為 <0>,表示該節點沒有大小訊息,通常是因為節點本身不需要描述內存大小。如果設為 <1>,則大小由1個單位表示;如果設為 <2>,則由2個單位表示,常見於需要描述較大內存區域的情況。

    假設我們有一個節點的 reg 屬性定義如下:

    reg = <0x1000 0x2000>;
    

    如果 #address-cells = <1>;#size-cells = <1>;,表示:

    • 地址部分是1個單位(32 bits):0x1000。 → 也就是說 0x1000 是一個 32bits 的地址
    • 大小部分是1個單位(32 bits):0x2000。 → 也就是說 0x2000 是一個 32bit 的型態
    cpus {
    		#address-cells = <1>;    
    		#size-cells = <0>;        
    
    		cpu0: cpu@0 {
    			compatible = "arm,cortex-a7";
    			device_type = "cpu";
    			reg = <0>;  /* address=0,因為#size-cells是0,没有length,等於只設定了起始位置,
    						   沒設定長度 */
    			clocks = <&scmi0_clk CK_SCMI0_MPU>;
    			clock-names = "cpu";
    			operating-points-v2 = <&cpu0_opp_table>;
    			nvmem-cells = <&part_number_otp>;
    			nvmem-cell-names = "part_number";
    			#cooling-cells = <2>;
    		};
    	};
    
    scmi_sram: sram@2ffff000 {
    		compatible = "mmio-sram";
    		reg = <0x2ffff000 0x1000>;
    		#address-cells = <1>;   /* 表示下面的 0X2FFFF000 是一個 32 bit 的地址*/
    		#size-cells = <1>;      /* 表示下面的 0x1000 是一個 32bit 的type*/
    		ranges = <0 0x2ffff000 0x1000>;
    
    		scmi0_shm: scmi_shm@0 {
    			reg = <0 0x80>;    /* 起始地址是0x0,長度是0x80 */
    		};
    
    		scmi1_shm: scmi_shm@200 {
    			reg = <0x200 0x80>;
    		};
    	};
    
    
  6. ranges

ranges 可以是空或找按照 <子匯流排地址,父匯流排地址>來寫,ranges 是一個 addr mapping table , 由子地址跟父地址還有地址空間所組成:

child-bus-address:子匯流排地址空間的實體地址,由父節點的#address-cells決定此實體地址所佔用的長度。

parent-bus-address:父匯流排地址空間的實體地址,同樣由父節點的#address-cells確定此實體地址所佔用的字長度

length:子地址空間的長度,由父節點的#size-cells確定此地址長度所佔用的字長度

如果ranges屬性值為空值,表示子地址空間和父地址空間完全相同,不需要轉換,例如:

soc
{
	compatible = "simple-bus";
	...
	ranges; # 這邊沒設定
};

ranges = <0 0x10000000 0x100000> /*指定一個1024kb(0x100000)的地址範圍,子地址空間的物理起始地址為0,父地址空間的物理起始地址為0x10000000。*/
sram: sram@10000000 {
	compatible = "mmio-sram";
	reg = <0x0 0x60000>;   /* 定义了sram设备寄存器的起始地址为0,寄存器长度0x60000*/
	#address-cells = <1>;
	#size-cells = <1>;
	ranges = <0 0x10000000 0x60000>;  /* 经过地址转换,sram设备可以从0x10000000开始进行读写操作,0x10000000 = 0x0+0x10000000
}; */

基本上不需要自己硬幹一個 device tree 出來,通常SoC廠商就會提供 .dts 檔案。在 yocto 當中可能會以patch 的形式,當你pull code 的時候一併打patch。大多時候我們都是用 Soc 廠商 的 .dts 檔案來開發。但我們還是需要知道語法跟邏輯是什麼,因為後續可能會很常使用到。

可以引用的有 .dtsi , .dts , .h ,這些檔案都是可以在設備樹當中引用的!

下方文件是 stm32mp157.dtsi ,當中只定義了 cpu , dsi,就沒有其他的,但可以看到第7行引用了 153.dtsi ,我們可以一路找發現最後引用到了 151.dtsi

https://ithelp.ithome.com.tw/upload/images/20240813/20146325QkavuNQUCg.png

在153當中呢我們看到了 cpu1:cpu@1 , 表示還有cpu 0 。

比對一下SPEC可以發現 確實還有另外一個core ,所以我們繼續往上層引用搜尋。

https://ithelp.ithome.com.tw/upload/images/20240813/20146325loNitLRMK7.png

https://ithelp.ithome.com.tw/upload/images/20240813/20146325XzAvZmhTFi.png

在151當中可以看到另外一個core就寫在這拉!因為大多是共用的,為了減少重複寫所以可以直接引用其他版本的!

https://ithelp.ithome.com.tw/upload/images/20240813/201463259wKx4OKsAC.png

其他的像是 clock timer 等等,也都可以在設備樹找到相關的設定。總之所有有關硬體的描述都會定義在設備樹當中。


上一篇
Day 16 。初入嵌入式開發-設備樹 (上)
下一篇
Day 18 。初入嵌入式開發- 使用官方的 BSP 來開發
系列文
門外漢的嵌入式地獄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言